﻿namespace Algo
{
    using System;
    using System.Diagnostics.Contracts;

    using Algo.Search;
    using Algo.Sort;

    using JetBrains.Annotations;

    public static class AlgoFactory
    {
        private static readonly Lazy<IDichotomySearchStrategy> BinarySearchStrategy = new Lazy<IDichotomySearchStrategy>(() => new BinarySearchStrategy());
        private static readonly Lazy<IDichotomySearchStrategy> GoldenSectionSearchStrategy = new Lazy<IDichotomySearchStrategy>(() => new GoldenSectionSearchStrategy());
        private static readonly Lazy<ISortStrategy> BubbleSortStrategy = new Lazy<ISortStrategy>(() => new BubbleSortStrategy());
        private static readonly Lazy<ISortStrategy> CocktailSortStrategy = new Lazy<ISortStrategy>(() => new CocktailSortStrategy());
        private static readonly Lazy<ISortStrategy> GnomeSortStrategy = new Lazy<ISortStrategy>(() => new GnomeSortStrategy());
        private static readonly Lazy<ISortStrategy> InsertsSortStrategy = new Lazy<ISortStrategy>(() => new InsertsSortStrategy());
        private static readonly Lazy<ISortStrategy> MergeSortStrategy = new Lazy<ISortStrategy>(() => new MergeSortStrategy());
        private static readonly Lazy<ISortStrategy> QuickSortStrategy = new Lazy<ISortStrategy>(() => new QuickSortStrategy());
        private static readonly Lazy<ISortStrategy> SelectionSortStrategy = new Lazy<ISortStrategy>(() => new SelectionSortStrategy());
        private static readonly Lazy<ISortStrategy> TreeSortStrategy = new Lazy<ISortStrategy>(() => new TreeSortStrategy());

        [NotNull] public static IDichotomySearchStrategy CreateBinarySearchStrategy()
        {
            Contract.Ensures(Contract.Result<IDichotomySearchStrategy>() != null);
            return BinarySearchStrategy.Value;
        }

        [NotNull]
        public static IDichotomySearchStrategy CreateGoldenSectionSearchStrategy()
        {
            Contract.Ensures(Contract.Result<IDichotomySearchStrategy>() != null);
            return GoldenSectionSearchStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateBubbleSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return BubbleSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateCocktailSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return CocktailSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateGnomeSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return GnomeSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateInsertsSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return InsertsSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateMergeSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return MergeSortStrategy.Value;
        }

        [NotNull]
        public static ISortStrategy CreateQuickSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return QuickSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateSelectionSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return SelectionSortStrategy.Value;
        }

        [NotNull] public static ISortStrategy CreateTreeSortStrategy()
        {
            Contract.Ensures(Contract.Result<ISortStrategy>() != null);
            return TreeSortStrategy.Value;
        }
    }
}
